package ua.com.minus1.lookbattle;

import android.app.AlertDialog;
import android.app.Dialog;
import android.app.ListActivity;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.*;
import com.google.gson.Gson;
import ua.com.minus1.lookbattle.models.*;
import ua.com.minus1.lookbattle.net.HttpManager;
import ua.com.minus1.lookbattle.net.ImageManager;
import ua.com.minus1.lookbattle.net.URLManager;
import ua.com.minus1.lookbattle.utils.AppPreferences;
import ua.com.minus1.lookbattle.utils.BundleCreator;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.List;

/**
 * Created with IntelliJ IDEA.
 * User: Flash
 * Date: 17.07.12
 * Time: 18:04
 * To change this template use File | Settings | File Templates.
 */
public class MyLooksActivity extends ListActivity {
    private HttpManager httpManager;
    private ImageManager imageManager;
    private static final int DIALOG_CONVERT = 0;
    private static final int DIALOG_INCORRECT_CODE = 1;
    private static final int ADD_LOOK = 0;
    private static final int LOOK_INFO = 1;
    private String uuid;
    private int catId;
    private AppPreferences preferences;
    private TextView emptyText;
    private TextView clickText;
    private CatsList catsList;
    private View progress;
    private LooksResult looksResult;
    private View content;
    private LoginView loginView;



    //TODO: save scroll position on orientation changes

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.my_looks);

        imageManager = new ImageManager(this, CacheFolder.IMAGES_MY_LOOKS);
        httpManager = new HttpManager(this, CacheFolder.HTTP_MY_LOOKS);

        if(savedInstanceState != null){
            catId = BundleCreator.readCategory(savedInstanceState);
        } else {
            clearCache();
            catId = BundleCreator.readCategory(getIntent().getExtras());
        }

        preferences = new AppPreferences(this);
        uuid = preferences.getUUID();
        setupViews();
        clickText.setText(String.valueOf(preferences.getClicks()));

        if (preferences.getRegistered()) {
            content.setVisibility(View.VISIBLE);
            loadLooks();
        } else {
            loginView.setOnRegisterListener(new OnUserRegisterListener());
            loginView.inflate();
            loginView.setVisibility(View.VISIBLE);
        }
    }

    @Override
    protected void onSaveInstanceState(Bundle outState) {
        BundleCreator creator = new BundleCreator(outState);
        creator.writeCategory(catId);
        //BundleCreator.writeBonuses(outState, itemsBonuses);
    }

    private void setupViews() {
        loginView = (LoginView) findViewById(R.id.loginView);
        content = findViewById(R.id.myLooksContent);
        progress = findViewById(R.id.myLooksProgress);
        emptyText = (TextView) findViewById(R.id.myLooksEmptyText);
        clickText = (TextView) findViewById(R.id.clicksText);
        catsList = (CatsList) findViewById(R.id.myLooksCatsList);
        catsList.setOnItemClickListener(new CatsList.OnItemClickListener() {
            public void onItemClick(CatItemFactory.CatItem catItem) {
                catId = catItem.catId;
                loadLooks();
            }
        });
    }

    public void cancelRegistration(View view) {
        finish();
    }

    private void loadLooks() {
        progress.setVisibility(View.VISIBLE);
        emptyText.setVisibility(View.GONE);
        setListAdapter(null);
        httpManager.loadClass(URLManager.getMyLooksURL(uuid, catId), LooksResult.class, new HttpManager.HttpResultHandler<LooksResult>() {
            public void onResultLoadComplete(LooksResult result) {
                looksResult = result;
                progress.setVisibility(View.GONE);
                if (looksResult != null) {
                    Log.i(MyLooksActivity.class.getName(), "Looks request result " + looksResult);
                    List<Look> looks = looksResult.looks;
                    setListAdapter(new LooksAdapter(looks));
                } else {
                    emptyText.setVisibility(View.VISIBLE);
                    Log.i(MyLooksActivity.class.getName(), "Looks request result is null");
                }

            }
        }, HttpManager.USE_CACHE);
    }

    public void addLook(View view) {
        BundleCreator creator = new BundleCreator();
        creator.writeCategory(catId);
        Intent intent = new Intent(this, TakePictureActivity.class);
        intent.putExtras(creator.create());
        startActivityForResult(intent, ADD_LOOK);
    }

    @Override
    protected Dialog onCreateDialog(int id) {
        switch (id) {
            case DIALOG_CONVERT:
                return new ConvertDialog(this).setConvertListener(new ConvertDialog.OnConvertListener() {
                    public void onClick(DialogInterface dialogInterface, int position, int lookId, int bonuses) {
                        if (bonuses != 0) {
                            final int itemPos = position;
                            String url = bonuses > 0 ? URLManager.getBonusUpUrl(uuid, catId, lookId, bonuses) : URLManager.getBonusRefundUrl(uuid, catId, lookId, Math.abs(bonuses));
                            Log.i(MyLooksActivity.class.getName(), "request for bonus update catId: " + catId + " lookId: " + lookId + " bonuses: "+bonuses + " url: " + url);
                            httpManager.loadClass(url, BonusConvertResult.class, new HttpManager.HttpResultHandler<BonusConvertResult>() {
                                public void onResultLoadComplete(BonusConvertResult result) {
                                    Log.i(MyLooksActivity.class.getName(), "bonus convert result: " + result.toString());
                                    preferences.setClicks(result.clicks);
                                    updateClicks(result.clicks);
                                    updateItemBonuses(itemPos, result.bonuses);
                                }
                            });
                        }
                        dialogInterface.cancel();
                    }
                }
                );
            case DIALOG_INCORRECT_CODE:
                AlertDialog.Builder builder = new AlertDialog.Builder(this);
                builder.setTitle("Wrong code")
                        .setMessage("This is the wrong code. Please try again.")
                        .setPositiveButton("Try again", new DialogInterface.OnClickListener() {
                            public void onClick(DialogInterface dialogInterface, int i) {
                                loginView.reenterCode();
                                dialogInterface.dismiss();
                            }
                        })
                        .setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
                            public void onClick(DialogInterface dialogInterface, int i) {
                                 loginView.reset();
                                dialogInterface.dismiss();
                            }
                        });
                return builder.create();
            default:
                return null;
        }
    }

    private void updateItemBonuses(int position, int bonuses) {
         looksResult.looks.get(position).bonuses = bonuses;
        updateCache(looksResult);


        ListView listView = getListView();
        int visiblePos = listView.getFirstVisiblePosition() - listView.getHeaderViewsCount();
        int updatedPos = position - visiblePos;
        Log.i(MyLooksActivity.class.getName(), "on list item bonus update position in the list: " + updatedPos);
        if (updatedPos >= 0 && position < listView.getChildCount()) {
            View itemView = listView.getChildAt(updatedPos);
            LooksAdapter adapter = (LooksAdapter) listView.getAdapter();
            adapter.updateItemBonuses(position, itemView, bonuses);
        }
    }

    private void updateClicks(int c)
    {
        clickText.setText(String.valueOf(c));
    }

    private void updateCache(LooksResult looksResult) {
        Gson gson = new Gson();
        String jsonString = gson.toJson(looksResult);

        File file = httpManager.getCacheFile(URLManager.getMyLooksURL(uuid, catId));
        if(file.exists())
            file.delete();
        try {
            FileOutputStream out = new FileOutputStream(file);
            out.write(jsonString.getBytes());
            out.flush();
            out.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    @Override
    protected void onPrepareDialog(int id, Dialog dialog, Bundle args) {
        super.onPrepareDialog(id, dialog, args);
        switch (id) {
            case DIALOG_CONVERT:
                if(getListAdapter() != null)
                {
                    int position = args.getInt("position");
                    Look look = (Look) getListAdapter().getItem(position);
                    Log.i(MyLooksActivity.class.getName(), "on prepare convert dialog item position: " + position);
                    ((ConvertDialog) dialog).setParams(ConvertDialog.getBundle(position, look.lookId, look.bonuses, preferences.getClicks()));
                }
                break;
        }
    }

    //@Override
    protected void onListItemClick(ListView l, View v, int position, long id) {
        BundleCreator creator = new BundleCreator();
        creator.writePosition(position)
                .writeCategory(catId)
                .writeLookId(((Look) l.getAdapter().getItem(position)).lookId);

        Intent intent = new Intent(this, LookActivity.class);
        intent.putExtras(creator.create());
        startActivityForResult(intent, LOOK_INFO);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        Bundle bundle;
        if (resultCode == RESULT_OK) {
            switch (requestCode) {
                case ADD_LOOK:
                    clearCache();
                    loadLooks();
                    break;
                case LOOK_INFO:
                    if(data.getBooleanExtra("delete", false))
                    {
                        clearCache();
                        loadLooks();
                    } else {
                        bundle = data.getExtras();
                        Log.i(MyLooksActivity.class.getName(), "onActivityResult: position: " + BundleCreator.readPosition(bundle) + " bonuses: " + BundleCreator.readBonuses(bundle));
                        updateItemBonuses(BundleCreator.readPosition(bundle), BundleCreator.readBonuses(bundle));
                        updateClicks(BundleCreator.readClicks(bundle));
                    }
                    break;
            }
        }
    }

    //TODO: clean up images cache
    private void clearCache() {
        //imageManager.clearCache();
        httpManager.clearCache();
    }

    private class LooksAdapter extends ArrayAdapter<Look>{
        private LooksAdapter(List<Look> looks) {
            super(MyLooksActivity.this, R.layout.list_item_look, looks);
        }

        public void updateItemBonuses(int position, View convertView, int bonuses) {
            getItem(position).bonuses = bonuses;
            ViewHolder viewHolder = (ViewHolder) convertView.getTag();
            viewHolder.bonuses.setText(String.valueOf(bonuses));
        }

        @Override
        public View getView(int position, View convertView, ViewGroup parent) {
            final ViewHolder viewHolder;

            final Look lookItem = getItem(position);

            if (convertView == null) {
                LayoutInflater inflater = (LayoutInflater) getContext().getSystemService(Context.LAYOUT_INFLATER_SERVICE);
                convertView = inflater.inflate(R.layout.list_item_look, null);

                viewHolder = new ViewHolder();
                viewHolder.image = (ImageView) convertView.findViewById(R.id.lookItemImage);
                viewHolder.progress = convertView.findViewById(R.id.lookItemProgress);
                viewHolder.battles = (TextView) convertView.findViewById(R.id.lookRatesBattles);
                viewHolder.awards = (TextView) convertView.findViewById(R.id.lookRatesLocalPace);
                viewHolder.winnings = (TextView) convertView.findViewById(R.id.lookRatesWinnings);
                viewHolder.bonuses = (TextView) convertView.findViewById(R.id.lookBonuses);
                viewHolder.convertBtn = (Button) convertView.findViewById(R.id.lookItemConvertBtn);
                viewHolder.convertBtn.setOnClickListener(new View.OnClickListener() {
                    public void onClick(View view) {
                        Bundle bundle = new Bundle();
                        bundle.putInt("position", viewHolder.position);
                        showDialog(DIALOG_CONVERT, bundle);
                    }
                });
                convertView.setTag(viewHolder);
            } else
                viewHolder = (ViewHolder) convertView.getTag();

            viewHolder.position = position;
            viewHolder.image.setImageBitmap(null);
            viewHolder.progress.setVisibility(View.VISIBLE);
            viewHolder.battles.setText(String.valueOf(lookItem.battles));
            viewHolder.awards.setText(String.valueOf(lookItem.awards));
            viewHolder.winnings.setText(String.valueOf(lookItem.winnings));
            viewHolder.bonuses.setText(String.valueOf(lookItem.bonuses));
//            Log.i(MyLooksActivity.class.getName(), lookItem.image);

            imageManager.loadBitmap(lookItem.image, viewHolder.image, new ImageManager.BitmapLoadListener() {
                public void onLoadComplete(Bitmap bitmap) {
                    viewHolder.progress.setVisibility(View.GONE);
                    //Log.i(MyLooksActivity.class.getName(), "image loaded");
                }
            }, ImageManager.USE_CACHE);

            return convertView;
        }

        private class ViewHolder {
            public int position;
            public ImageView image;
            public View progress;
            public TextView battles;
            public TextView awards;
            public TextView bonuses;
            public Button convertBtn;
            public TextView winnings;
        }
    }

    private class OnUserRegisterListener implements LoginView.OnRegisterListener {
        public void onIncorrectCode() {
            showDialog(DIALOG_INCORRECT_CODE);
        }

        public void onRegister(boolean success) {
            if(success)
            {
                preferences.setRegistered(true);
                updateClicks(preferences.getClicks());
                loadLooks();
                content.setVisibility(View.VISIBLE);
                loginView.setVisibility(View.GONE);
            } else
                finish();
        }
    }
}
